﻿using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Devonline.Core;

/// <summary>
/// 自定义时间格式化器
/// </summary>
public class DateTimeConverter : JsonConverter<DateTime>
{
    /// <summary>
    /// 时间格式
    /// </summary>
    private readonly string _formatter;
    /// <summary>
    /// 格式使用完整的时间格式
    /// </summary>
    /// <param name="formatter"></param>
    public DateTimeConverter(string formatter) => _formatter = formatter;

    /// <summary>
    /// 反序列化方法, 从字符串中读取的方法
    /// </summary>
    /// <param name="reader"></param>
    /// <param name="typeToConvert"></param>
    /// <param name="options"></param>
    /// <returns></returns>
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (!reader.TryGetDateTime(out DateTime value) && DateTime.TryParseExact(reader.GetString(), _formatter, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out DateTime dateTimeValue))
        {
            return dateTimeValue;
        }

        return value;
    }
    /// <summary>
    /// 序列化方法, 写入到字符串中的方法
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="value"></param>
    /// <param name="options"></param>
    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(_formatter, CultureInfo.CurrentCulture));
    }
}

/// <summary>
/// 自定义时间格式化器
/// </summary>
public class DateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
    /// <summary>
    /// 时间格式
    /// </summary>
    private readonly string _formatter;
    /// <summary>
    /// 格式使用完整的时间格式
    /// </summary>
    /// <param name="formatter"></param>
    public DateTimeOffsetConverter(string formatter) => _formatter = formatter;

    /// <summary>
    /// 反序列化方法, 从字符串中读取的方法
    /// </summary>
    /// <param name="reader"></param>
    /// <param name="typeToConvert"></param>
    /// <param name="options"></param>
    /// <returns></returns>
    public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (!reader.TryGetDateTime(out DateTime value) && DateTimeOffset.TryParseExact(reader.GetString(), _formatter, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out DateTimeOffset dateTimeValue))
        {
            return dateTimeValue;
        }

        return value;
    }
    /// <summary>
    /// 序列化方法, 写入到字符串中的方法
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="value"></param>
    /// <param name="options"></param>
    public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString(_formatter, CultureInfo.CurrentCulture));
}

/// <summary>
/// 自定义日期类型格式化器
/// </summary>
public class DateOnlyConverter : JsonConverter<DateOnly>
{
    /// <summary>
    /// 时间格式
    /// </summary>
    private readonly string _formatter;
    /// <summary>
    /// 构造方法
    /// </summary>
    /// <param name="formatter"></param>
    public DateOnlyConverter(string formatter) => _formatter = formatter;

    /// <summary>
    /// 反序列化方法, 从字符串中读取的方法
    /// </summary>
    /// <param name="reader"></param>
    /// <param name="typeToConvert"></param>
    /// <param name="options"></param>
    /// <returns></returns>
    public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (DateOnly.TryParseExact(reader.GetString(), _formatter, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out DateOnly value))
        {
            return value;
        }

        return DateOnly.MinValue;
    }
    /// <summary>
    /// 序列化方法, 写入到字符串中的方法
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="value"></param>
    /// <param name="options"></param>
    public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString(_formatter, CultureInfo.CurrentCulture));
}

/// <summary>
/// 自定义时间类型格式化器
/// </summary>
public class TimeOnlyConverter : JsonConverter<TimeOnly>
{
    /// <summary>
    /// 时间格式
    /// </summary>
    private readonly string _formatter;
    /// <summary>
    /// 构造方法
    /// </summary>
    /// <param name="formatter"></param>
    public TimeOnlyConverter(string formatter) => _formatter = formatter;

    /// <summary>
    /// 反序列化方法, 从字符串中读取的方法
    /// </summary>
    /// <param name="reader"></param>
    /// <param name="typeToConvert"></param>
    /// <param name="options"></param>
    /// <returns></returns>
    public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (TimeOnly.TryParseExact(reader.GetString(), _formatter, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out TimeOnly value))
        {
            return value;
        }

        return TimeOnly.MinValue;
    }
    /// <summary>
    /// 序列化方法, 写入到字符串中的方法
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="value"></param>
    /// <param name="options"></param>
    public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString(_formatter, CultureInfo.CurrentCulture));
}